Live Search

Hello,

our requirements have very long names.

Is it possible to create a dropdown menĂ¼ with live search results?

Thank you


dxlinformatik - Wed Feb 05 08:07:43 EST 2014

Re: Live Search
pommCannelle - Wed Feb 05 11:10:31 EST 2014

Using input from master Mamsch, i've built a quick start ...

pragma runLim, 0   

Module m = current
if ( null m ) {
    infoBox "Need a current Module to be used ..."
    halt
}

/* GLOBALS */
// -- Timer
int giCurrentProgress = 0
int giMaxProgress     = 0

// -- Dialog  
DB diag
DBE fieldToSurvey  
DBE valueList
string listOfValue[]

// -- Variables
string storedValue = ""  
string currentValue = ""

Skip skpListID = null

string tmpID = ""
Object o

/* CAPTURE THE VALUES */
void fillReferenceList ( string attributeName ){
    if ( ! null skpListID ) { delete(skpListID); skpListID = null }
    skpListID = createString()
    for o in m do {
        if ( probeAttr_(o, attributeName) "" == "" ) continue
        put( skpListID, probeAttr_(o, attributeName) "", o )
    }
}

/* TIMER MANAGEMENT */
void TimerCallback (DBE x) {
    int tStart = getTickCount_()
    // keep working for 75 ms, letting dxl IDLE 25 ms
    while (getTickCount_ - tStart < 75) {
        // Survey part ...  
        currentValue = get fieldToSurvey
        if ( currentValue"" != storedValue"" ) {
            storedValue = currentValue ""
            empty valueList
            for o in skpListID do {
                tmpID = ( string key skpListID )
                if ( ! matches(currentValue"", tmpID"") ) continue
                insert( valueList, noElems valueList, tmpID"" )
            }
        }  
        // manage the timer      
        // set (sbStatus, "Current: " giCurrentProgress "\n")
        giCurrentProgress++
        sleep_ 10
    }
    if (giCurrentProgress > giMaxProgress) { stopTimer theTimer }
}   

void startWork (DBE x) {
    giMaxProgress = 100000 // yes ... that will end the search feature ;)
    startTimer theTimer
}   

void pauseWork (DBE x) { stopTimer theTimer }

/* IMPLEMENT THE INTERFACE */
void closeFunc (DB x) {
    pauseWork( null DBE )
    delete skpListID
    release x
    hide x
}   

void doMakeSelection(DBE x) {
    string selectedValue = get valueList
    find ( skpListID, selectedValue, o )
    current = o
    refresh m
    refreshExplorer m
}

void makeGUI () {
    diag = centered "Hello"
    fieldToSurvey = field( diag, "", "", 40 )
    valueList = list ( diag, "Corresponding Value", 10, listOfValue )
    set ( valueList, doMakeSelection )
    
    close (diag, false, closeFunc)

    int sbSections[] = {2000}
    sbStatus = statusBar (diag, "", sbSections)
    // Set timer to 100 ms  
    theTimer = timer(diag, 0.1, TimerCallback, "ticktock")
    stopTimer theTimer
    realize (diag){
        setSize(diag, 300, 260)
        fillReferenceList "IE PUID"
        startWork(null DBE)
    }
    show diag
}   

makeGUI()

The call to the fillReferenceList function allow you to select the attribute containing your key ....

I hope this can be helpfull ;)

Re: Live Search
Mathias Mamsch - Wed Feb 05 16:09:21 EST 2014

pommCannelle - Wed Feb 05 11:10:31 EST 2014

Using input from master Mamsch, i've built a quick start ...

pragma runLim, 0   

Module m = current
if ( null m ) {
    infoBox "Need a current Module to be used ..."
    halt
}

/* GLOBALS */
// -- Timer
int giCurrentProgress = 0
int giMaxProgress     = 0

// -- Dialog  
DB diag
DBE fieldToSurvey  
DBE valueList
string listOfValue[]

// -- Variables
string storedValue = ""  
string currentValue = ""

Skip skpListID = null

string tmpID = ""
Object o

/* CAPTURE THE VALUES */
void fillReferenceList ( string attributeName ){
    if ( ! null skpListID ) { delete(skpListID); skpListID = null }
    skpListID = createString()
    for o in m do {
        if ( probeAttr_(o, attributeName) "" == "" ) continue
        put( skpListID, probeAttr_(o, attributeName) "", o )
    }
}

/* TIMER MANAGEMENT */
void TimerCallback (DBE x) {
    int tStart = getTickCount_()
    // keep working for 75 ms, letting dxl IDLE 25 ms
    while (getTickCount_ - tStart < 75) {
        // Survey part ...  
        currentValue = get fieldToSurvey
        if ( currentValue"" != storedValue"" ) {
            storedValue = currentValue ""
            empty valueList
            for o in skpListID do {
                tmpID = ( string key skpListID )
                if ( ! matches(currentValue"", tmpID"") ) continue
                insert( valueList, noElems valueList, tmpID"" )
            }
        }  
        // manage the timer      
        // set (sbStatus, "Current: " giCurrentProgress "\n")
        giCurrentProgress++
        sleep_ 10
    }
    if (giCurrentProgress > giMaxProgress) { stopTimer theTimer }
}   

void startWork (DBE x) {
    giMaxProgress = 100000 // yes ... that will end the search feature ;)
    startTimer theTimer
}   

void pauseWork (DBE x) { stopTimer theTimer }

/* IMPLEMENT THE INTERFACE */
void closeFunc (DB x) {
    pauseWork( null DBE )
    delete skpListID
    release x
    hide x
}   

void doMakeSelection(DBE x) {
    string selectedValue = get valueList
    find ( skpListID, selectedValue, o )
    current = o
    refresh m
    refreshExplorer m
}

void makeGUI () {
    diag = centered "Hello"
    fieldToSurvey = field( diag, "", "", 40 )
    valueList = list ( diag, "Corresponding Value", 10, listOfValue )
    set ( valueList, doMakeSelection )
    
    close (diag, false, closeFunc)

    int sbSections[] = {2000}
    sbStatus = statusBar (diag, "", sbSections)
    // Set timer to 100 ms  
    theTimer = timer(diag, 0.1, TimerCallback, "ticktock")
    stopTimer theTimer
    realize (diag){
        setSize(diag, 300, 260)
        fillReferenceList "IE PUID"
        startWork(null DBE)
    }
    show diag
}   

makeGUI()

The call to the fillReferenceList function allow you to select the attribute containing your key ....

I hope this can be helpfull ;)

Just some feedback to that example:

  1. I think you can remove the timing constraints here, since you do not really do 'background' work here (Line 43)
  2. You are stopping, then starting the timer (Line 98, 65). Note that DXL is single threaded, so there is no need to pause the timer. The first time it will be executed is after the 'show'.
  3. Do you really need a timer here? Will a 'change' event on fieldToSurvey not be enough?
  4. In your Skip you only put one object per value. What if multiple objects have the same value? Maybe here you want to use an Array and a Skip indexing the array line (don't use Skip in Skip or Array in Skip because of allocations).
  5. Your giMaxProgress seems arbitrarily chosen. It looks to me the search will be executed about 100 seconds (100000 / 10ms) and then stopped.
  6. matches () works with regular expressions internally. Putting it in a loop like this is kind of madness, because internally the regular expression string is parsed every time. Also beware of invalid regular expression strings.
  7. You should remove unused functions from the example, like the status bar, pauseFunc, etc.

Maybe its helpful, Regards, Mathias

Re: Live Search
pommCannelle - Mon Feb 10 10:20:16 EST 2014

Mathias Mamsch - Wed Feb 05 16:09:21 EST 2014

Just some feedback to that example:

  1. I think you can remove the timing constraints here, since you do not really do 'background' work here (Line 43)
  2. You are stopping, then starting the timer (Line 98, 65). Note that DXL is single threaded, so there is no need to pause the timer. The first time it will be executed is after the 'show'.
  3. Do you really need a timer here? Will a 'change' event on fieldToSurvey not be enough?
  4. In your Skip you only put one object per value. What if multiple objects have the same value? Maybe here you want to use an Array and a Skip indexing the array line (don't use Skip in Skip or Array in Skip because of allocations).
  5. Your giMaxProgress seems arbitrarily chosen. It looks to me the search will be executed about 100 seconds (100000 / 10ms) and then stopped.
  6. matches () works with regular expressions internally. Putting it in a loop like this is kind of madness, because internally the regular expression string is parsed every time. Also beware of invalid regular expression strings.
  7. You should remove unused functions from the example, like the status bar, pauseFunc, etc.

Maybe its helpful, Regards, Mathias

Hi Mathias.

Thx for the inputs !
I had a look in the help ... And i can't find any reference to your point 3 ... How can i add a change event on a DBE ?? 

With a such event management, i aggree that a timer is not needed ...
I'll post a corrected version with event management if you can provide the feature to use :)

Regards ...

Re: Live Search
KBSri - Tue Feb 11 01:33:51 EST 2014

pommCannelle - Mon Feb 10 10:20:16 EST 2014

Hi Mathias.

Thx for the inputs !
I had a look in the help ... And i can't find any reference to your point 3 ... How can i add a change event on a DBE ?? 

With a such event management, i aggree that a timer is not needed ...
I'll post a corrected version with event management if you can provide the feature to use :)

Regards ...

Hey,

I just went through the code.Can you please xplain what is stopTimer, the timer?

Whats the use of stopTimer function? the timer should be declared?

I am getting error while running the script.

regards.

Re: Live Search
pommCannelle - Tue Feb 11 04:51:16 EST 2014

Mathias Mamsch - Wed Feb 05 16:09:21 EST 2014

Just some feedback to that example:

  1. I think you can remove the timing constraints here, since you do not really do 'background' work here (Line 43)
  2. You are stopping, then starting the timer (Line 98, 65). Note that DXL is single threaded, so there is no need to pause the timer. The first time it will be executed is after the 'show'.
  3. Do you really need a timer here? Will a 'change' event on fieldToSurvey not be enough?
  4. In your Skip you only put one object per value. What if multiple objects have the same value? Maybe here you want to use an Array and a Skip indexing the array line (don't use Skip in Skip or Array in Skip because of allocations).
  5. Your giMaxProgress seems arbitrarily chosen. It looks to me the search will be executed about 100 seconds (100000 / 10ms) and then stopped.
  6. matches () works with regular expressions internally. Putting it in a loop like this is kind of madness, because internally the regular expression string is parsed every time. Also beware of invalid regular expression strings.
  7. You should remove unused functions from the example, like the status bar, pauseFunc, etc.

Maybe its helpful, Regards, Mathias

Here after a corrected version ... 

( point 4 -> i deal with requirements and use a unique ID to build my skip ... same value can't be found twice ;) )

pragma encoding, "UTF-8"
pragma runLim, 0   

Module m = current 
if ( null m ) {
    infoBox "Need a current Module to be used ..."
    halt
}

AttrDef ad = find ( m, "IE PUID" ) 
if (null ad) {
    infoBox "The current module have to be an IRDRMFAO one."
    halt
}

/* GLOBALS */
// -- Dialog  
DB diag 

DBE theTimer

DBE fieldToSurvey  

DBE radioCase
string choicesCASE[] = { "Yes", "No" }

DBE labelList
DBE valueList 
string listOfValue[]

// -- Variables
string storedValue = ""  
string currentValue = "" 

Skip skpListID = null
Skip skpListValue = null 

string tmpID = ""
Object o, otmp

bool caseSensitive = true

/* deal with data */
Skip fillReferenceList ( string attributeName ) {
    Skip skpREZ = createString()
    for o in m do {
        if ( null probeAttr_(o, attributeName"")) continue 
        put( skpREZ, probeAttr_(o, attributeName "") "", o)
    }
    return skpREZ
}

Skip split ( string s, char c ) {   
   Skip split_string = create
   int deb = 0; int i; int index = 0
   for ( i=0; i<length(s)-1; i++ ) {
      if ( s[i] != c ) continue
      put( split_string, index++, s[deb++:i-1] )
   }
   if ( s[i] == c ) i--
   put ( split_string, index, s[deb:i] )
   return split_string
}

Skip findAllValues(string val){
    int rez = -1
    Object oREZ = null 
    Skip skpREZ = null 
    
    Skip skpValues = split ( val"", ' ' ) 
    bool objectOK = true
    string valPart = "" 
    string stmp = ""
    string strbuff = ""
    
    // Deal with a list of attribute to parse ...
        Skip skpAttrToSearchIn = createString()
    put ( skpAttrToSearchIn, "Object Text", "Object Text" )
    
    for stmp in skpAttrToSearchIn do { 
        for o in skpListID do {
            strbuff = probeAttr_(o, stmp"")
            objectOK = true 
            for valPart in skpValues do {
                Regexp r = null 
                if ( ! caseSensitive ){ 
                    r = regexp2( lower(valPart) )
                    objectOK = objectOK && (r(lower(strbuff)))
                } else {
                    r = regexp2(valPart)
                    objectOK = objectOK && (r(strbuff))
                }
                delete r 
            }
            if ( objectOK ) {
                string ID = (string key skpListID)
                if (find( skpListID, ID"", oREZ)){
                    if (null skpREZ) skpREZ = createString()
                    put (skpREZ, oREZ."ie puid""", oREZ) 
                } 
            }
        }
    }
    // specific treatment for identifier
    for o in skpListID do {
        stmp = (string key skpListID)
        objectOK = false 
        for valPart in skpValues do {
            Regexp r = regexp2(valPart)
            objectOK = r(stmp)
            delete r
            if ( objectOK ) break
        }
        if ( objectOK ) {
            string ID = (string key skpListID)
            if (find( skpListID, ID"", oREZ)){
                if (null skpREZ) skpREZ = createString()
                put (skpREZ, oREZ."ie puid""", oREZ) 
            } 
        }
    }
    
    delete skpValues; skpValues = null 
    delete skpAttrToSearchIn; skpAttrToSearchIn = null 
    return skpREZ
}


/* TIMER MANAGEMENT */
void TimerCallback (DBE x) { 
    int tStart = getTickCount_() 
    Skip skptmp = null 
    // keep working for 75 ms, letting dxl IDLE 25 ms 
    while (getTickCount_ - tStart < 75) { 
        // Survey part ...  
        currentValue = get fieldToSurvey 
        if ( currentValue"" != storedValue"" ) {
            storedValue = currentValue ""
            empty valueList
            skptmp = findAllValues(currentValue"")
            if ( null skptmp ) continue
            for otmp in skptmp do {
                insert( valueList, noElems valueList, otmp."ie puid" "" )
                set ( valueList, noElems valueList - 1, 0, otmp."ie puid" "" ) 
                set ( valueList, noElems valueList - 1, 1, otmp."object text" "" ) 
            }
            delete skptmp; skptmp = null 
        }  
        sleep_ 10 
    }  
}   

void startWork (DBE x) { startTimer theTimer }   
void pauseWork (DBE x) { stopTimer theTimer } 

//-- Actions of the GUI
void closeFunc (DB x) { 
    pauseWork( null DBE )
    if (! null skpListID) delete skpListID 
    if (! null skpListValue) delete skpListValue
    release x; hide x 
        destroy x
}   

void doActivateList(DBE x, int pos) {
    string selectedValue = get(valueList, pos)
    find ( skpListID, selectedValue, o ) 
    current = o 
    refresh m
    refreshExplorer m
}

void doSelectCase(DBE x){
    int selectedPos = get radioCase
    caseSensitive = ( selectedPos == 0 )
}

void doSelectList(DBE x, int pos){ /* do Nothing */ }
void doDeselectList(DBE x, int pos){ /* do Nothing */ }

/* IMPLEMENT THE INTERFACE */
void left( DBE x, DBE y ){ x->"top"->"aligned"->y; x->"left"->"spaced"->y }
void line( DBE x[] ){ int n = sizeof x; int i; for i in 1:n-1 do left ( x[i], x[i-1] ) }

void makeGUI () { 
    diag = centered "Dynamic Search - Text & PUID" 
    fieldToSurvey = field( diag, "", "", 40 )
    
    radioCase = radioBox(diag, "Case sensitive ?", choicesCASE, 0)
    set(radioCase, doSelectCase)
    line(fieldToSurvey, radioCase) 
    
    labelList = label( diag, "Corresponding Value" )
    valueList = listView ( diag, 0, 200, 10, listOfValue )
    set ( valueList, doActivateList, doDeselectList, doActivateList )
    
    close (diag, false, closeFunc) 

    // Set timer to 100 ms  
    theTimer = timer(diag, 0.1, TimerCallback, "ticktock") 
    realize (diag){ 
        setSize(diag, 640, 360)
        insertColumn( valueList, 0, "IE PUID", 140, iconNone )
        insertColumn( valueList, 1, "Object Text", 470, iconNone )
        skpListID = fillReferenceList("IE PUID")
        startWork(null DBE)
    }
    show diag 
}   

makeGUI()

I don't want validation button for the modification of the searched string, that's why i'm using the timer. 

Any input to deal with a 'modification event' on a DBE ??

Re: Live Search
dxlinformatik - Tue Feb 11 11:38:27 EST 2014

pommCannelle - Tue Feb 11 04:51:16 EST 2014

Here after a corrected version ... 

( point 4 -> i deal with requirements and use a unique ID to build my skip ... same value can't be found twice ;) )

pragma encoding, "UTF-8"
pragma runLim, 0   

Module m = current 
if ( null m ) {
    infoBox "Need a current Module to be used ..."
    halt
}

AttrDef ad = find ( m, "IE PUID" ) 
if (null ad) {
    infoBox "The current module have to be an IRDRMFAO one."
    halt
}

/* GLOBALS */
// -- Dialog  
DB diag 

DBE theTimer

DBE fieldToSurvey  

DBE radioCase
string choicesCASE[] = { "Yes", "No" }

DBE labelList
DBE valueList 
string listOfValue[]

// -- Variables
string storedValue = ""  
string currentValue = "" 

Skip skpListID = null
Skip skpListValue = null 

string tmpID = ""
Object o, otmp

bool caseSensitive = true

/* deal with data */
Skip fillReferenceList ( string attributeName ) {
    Skip skpREZ = createString()
    for o in m do {
        if ( null probeAttr_(o, attributeName"")) continue 
        put( skpREZ, probeAttr_(o, attributeName "") "", o)
    }
    return skpREZ
}

Skip split ( string s, char c ) {   
   Skip split_string = create
   int deb = 0; int i; int index = 0
   for ( i=0; i<length(s)-1; i++ ) {
      if ( s[i] != c ) continue
      put( split_string, index++, s[deb++:i-1] )
   }
   if ( s[i] == c ) i--
   put ( split_string, index, s[deb:i] )
   return split_string
}

Skip findAllValues(string val){
    int rez = -1
    Object oREZ = null 
    Skip skpREZ = null 
    
    Skip skpValues = split ( val"", ' ' ) 
    bool objectOK = true
    string valPart = "" 
    string stmp = ""
    string strbuff = ""
    
    // Deal with a list of attribute to parse ...
        Skip skpAttrToSearchIn = createString()
    put ( skpAttrToSearchIn, "Object Text", "Object Text" )
    
    for stmp in skpAttrToSearchIn do { 
        for o in skpListID do {
            strbuff = probeAttr_(o, stmp"")
            objectOK = true 
            for valPart in skpValues do {
                Regexp r = null 
                if ( ! caseSensitive ){ 
                    r = regexp2( lower(valPart) )
                    objectOK = objectOK && (r(lower(strbuff)))
                } else {
                    r = regexp2(valPart)
                    objectOK = objectOK && (r(strbuff))
                }
                delete r 
            }
            if ( objectOK ) {
                string ID = (string key skpListID)
                if (find( skpListID, ID"", oREZ)){
                    if (null skpREZ) skpREZ = createString()
                    put (skpREZ, oREZ."ie puid""", oREZ) 
                } 
            }
        }
    }
    // specific treatment for identifier
    for o in skpListID do {
        stmp = (string key skpListID)
        objectOK = false 
        for valPart in skpValues do {
            Regexp r = regexp2(valPart)
            objectOK = r(stmp)
            delete r
            if ( objectOK ) break
        }
        if ( objectOK ) {
            string ID = (string key skpListID)
            if (find( skpListID, ID"", oREZ)){
                if (null skpREZ) skpREZ = createString()
                put (skpREZ, oREZ."ie puid""", oREZ) 
            } 
        }
    }
    
    delete skpValues; skpValues = null 
    delete skpAttrToSearchIn; skpAttrToSearchIn = null 
    return skpREZ
}


/* TIMER MANAGEMENT */
void TimerCallback (DBE x) { 
    int tStart = getTickCount_() 
    Skip skptmp = null 
    // keep working for 75 ms, letting dxl IDLE 25 ms 
    while (getTickCount_ - tStart < 75) { 
        // Survey part ...  
        currentValue = get fieldToSurvey 
        if ( currentValue"" != storedValue"" ) {
            storedValue = currentValue ""
            empty valueList
            skptmp = findAllValues(currentValue"")
            if ( null skptmp ) continue
            for otmp in skptmp do {
                insert( valueList, noElems valueList, otmp."ie puid" "" )
                set ( valueList, noElems valueList - 1, 0, otmp."ie puid" "" ) 
                set ( valueList, noElems valueList - 1, 1, otmp."object text" "" ) 
            }
            delete skptmp; skptmp = null 
        }  
        sleep_ 10 
    }  
}   

void startWork (DBE x) { startTimer theTimer }   
void pauseWork (DBE x) { stopTimer theTimer } 

//-- Actions of the GUI
void closeFunc (DB x) { 
    pauseWork( null DBE )
    if (! null skpListID) delete skpListID 
    if (! null skpListValue) delete skpListValue
    release x; hide x 
        destroy x
}   

void doActivateList(DBE x, int pos) {
    string selectedValue = get(valueList, pos)
    find ( skpListID, selectedValue, o ) 
    current = o 
    refresh m
    refreshExplorer m
}

void doSelectCase(DBE x){
    int selectedPos = get radioCase
    caseSensitive = ( selectedPos == 0 )
}

void doSelectList(DBE x, int pos){ /* do Nothing */ }
void doDeselectList(DBE x, int pos){ /* do Nothing */ }

/* IMPLEMENT THE INTERFACE */
void left( DBE x, DBE y ){ x->"top"->"aligned"->y; x->"left"->"spaced"->y }
void line( DBE x[] ){ int n = sizeof x; int i; for i in 1:n-1 do left ( x[i], x[i-1] ) }

void makeGUI () { 
    diag = centered "Dynamic Search - Text & PUID" 
    fieldToSurvey = field( diag, "", "", 40 )
    
    radioCase = radioBox(diag, "Case sensitive ?", choicesCASE, 0)
    set(radioCase, doSelectCase)
    line(fieldToSurvey, radioCase) 
    
    labelList = label( diag, "Corresponding Value" )
    valueList = listView ( diag, 0, 200, 10, listOfValue )
    set ( valueList, doActivateList, doDeselectList, doActivateList )
    
    close (diag, false, closeFunc) 

    // Set timer to 100 ms  
    theTimer = timer(diag, 0.1, TimerCallback, "ticktock") 
    realize (diag){ 
        setSize(diag, 640, 360)
        insertColumn( valueList, 0, "IE PUID", 140, iconNone )
        insertColumn( valueList, 1, "Object Text", 470, iconNone )
        skpListID = fillReferenceList("IE PUID")
        startWork(null DBE)
    }
    show diag 
}   

makeGUI()

I don't want validation button for the modification of the searched string, that's why i'm using the timer. 

Any input to deal with a 'modification event' on a DBE ??

Thank you guys.

I think this will help me to implement it.

 

Great community.